/**
 * 数据库数据服务
 * 用于从 MongoDB 数据库获取数据，替代模拟数据
 * 注意：此服务只能在服务端运行
 */

// 动态导入 MongoDB，避免在客户端打包
let mongoDB: any = null
let HospitalData: any, DepartmentData: any, EquipmentData: any, AlertData: any, PatientFlowData: any, KPIData: any, POIData: any

// 在服务端初始化 MongoDB
async function initMongoDB() {
  if (typeof window === 'undefined' && !mongoDB) {
    const mongodbModule = await import('./mongodb')
    mongoDB = mongodbModule.mongoDB
    HospitalData = mongodbModule.HospitalData
    DepartmentData = mongodbModule.DepartmentData
    EquipmentData = mongodbModule.EquipmentData
    AlertData = mongodbModule.AlertData
    PatientFlowData = mongodbModule.PatientFlowData
    KPIData = mongodbModule.KPIData
    POIData = mongodbModule.POIData
  }
}

export interface RealTimeData {
  timestamp: Date
  hospital: HospitalData | null
  alerts: AlertData[]
  patientFlow: PatientFlowData[]
  departments: DepartmentData[]
  equipment: EquipmentData[]
  kpis: {
    bedUtilization: KPIData | null
    patientFlow: KPIData | null
    equipmentEfficiency: KPIData | null
    patientSatisfaction: KPIData | null
    emergencyResponse: KPIData | null
    averageWaitTime: KPIData | null
  }
}

class DatabaseService {
  private hospitalId: string = ''

  /**
   * 初始化服务
   */
  async initialize(): Promise<void> {
    try {
      // 在服务端初始化 MongoDB
      await initMongoDB()

      if (!mongoDB) {
        throw new Error('MongoDB 服务未初始化，可能是在客户端环境中运行')
      }

      await mongoDB.connect()

      // 获取默认医院ID
      const hospitals = await mongoDB.getHospitals()
      if (hospitals.length > 0) {
        this.hospitalId = hospitals[0].id
      } else {
        throw new Error('未找到医院数据，请先执行数据迁移')
      }
    } catch (error) {
      console.error('数据库服务初始化失败:', error)
      throw error
    }
  }

  /**
   * 获取所有实时数据
   */
  async getAllRealTimeData(): Promise<RealTimeData> {
    if (!this.hospitalId) {
      await this.initialize()
    }

    try {
      const [
        hospital,
        alerts,
        patientFlow,
        departments,
        equipment,
        kpis
      ] = await Promise.all([
        mongoDB.getHospital(this.hospitalId),
        mongoDB.getAlertsByHospital(this.hospitalId),
        mongoDB.getPatientFlowByHospital(this.hospitalId),
        mongoDB.getDepartmentsByHospital(this.hospitalId),
        mongoDB.getEquipmentByHospital(this.hospitalId),
        mongoDB.getKPIsByHospital(this.hospitalId)
      ])

      // 组织KPI数据
      const kpiMap = kpis.reduce((acc, kpi) => {
        acc[kpi.metric] = kpi
        return acc
      }, {} as Record<string, KPIData>)

      return {
        timestamp: new Date(),
        hospital,
        alerts,
        patientFlow,
        departments,
        equipment,
        kpis: {
          bedUtilization: kpiMap.bedUtilization || null,
          patientFlow: kpiMap.patientFlow || null,
          equipmentEfficiency: kpiMap.equipmentEfficiency || null,
          patientSatisfaction: kpiMap.patientSatisfaction || null,
          emergencyResponse: kpiMap.emergencyResponse || null,
          averageWaitTime: kpiMap.averageWaitTime || null
        }
      }
    } catch (error) {
      console.error('获取实时数据失败:', error)
      throw error
    }
  }

  /**
   * 获取医院信息
   */
  async getHospitalInfo(): Promise<HospitalData | null> {
    if (!this.hospitalId) {
      await this.initialize()
    }
    return await mongoDB.getHospital(this.hospitalId)
  }

  /**
   * 获取科室数据
   */
  async getDepartments(): Promise<DepartmentData[]> {
    if (!this.hospitalId) {
      await this.initialize()
    }
    return await mongoDB.getDepartmentsByHospital(this.hospitalId)
  }

  /**
   * 获取设备数据
   */
  async getEquipment(): Promise<EquipmentData[]> {
    if (!this.hospitalId) {
      await this.initialize()
    }
    return await mongoDB.getEquipmentByHospital(this.hospitalId)
  }

  /**
   * 获取告警数据
   */
  async getAlerts(): Promise<AlertData[]> {
    if (!this.hospitalId) {
      await this.initialize()
    }
    return await mongoDB.getAlertsByHospital(this.hospitalId)
  }

  /**
   * 获取患者流量数据
   */
  async getPatientFlow(date?: Date): Promise<PatientFlowData[]> {
    if (!this.hospitalId) {
      await this.initialize()
    }
    return await mongoDB.getPatientFlowByHospital(this.hospitalId, date)
  }

  /**
   * 获取KPI数据
   */
  async getKPIs(): Promise<KPIData[]> {
    if (!this.hospitalId) {
      await this.initialize()
    }
    return await mongoDB.getKPIsByHospital(this.hospitalId)
  }

  /**
   * 获取POI数据
   */
  async getPOIs(): Promise<POIData[]> {
    if (!this.hospitalId) {
      await this.initialize()
    }
    return await mongoDB.getPOIsByHospital(this.hospitalId)
  }

  /**
   * 添加新的告警
   */
  async addAlert(alert: Omit<AlertData, '_id' | 'id' | 'createdAt' | 'updatedAt'>): Promise<AlertData> {
    if (!this.hospitalId) {
      await this.initialize()
    }
    return await mongoDB.addAlert({
      ...alert,
      hospitalId: this.hospitalId
    })
  }

  /**
   * 添加新的POI
   */
  async addPOI(poi: Omit<POIData, '_id' | 'id' | 'createdAt' | 'updatedAt'>): Promise<POIData> {
    if (!this.hospitalId) {
      await this.initialize()
    }
    return await mongoDB.addPOI({
      ...poi,
      hospitalId: this.hospitalId
    })
  }

  /**
   * 更新KPI数据
   */
  async updateKPI(metric: string, value: number, trend: number, status: string): Promise<void> {
    if (!this.hospitalId) {
      await this.initialize()
    }

    const kpi: Omit<KPIData, '_id' | 'id' | 'createdAt' | 'updatedAt'> = {
      hospitalId: this.hospitalId,
      metric: metric as any,
      value,
      target: 85, // 默认目标值
      trend,
      status: status as any,
      timestamp: new Date(),
      metadata: {
        source: 'realtime_update'
      }
    }

    await mongoDB.addKPI(kpi)
  }

  /**
   * 订阅实时更新
   */
  subscribeToUpdates(callback: (data: RealTimeData) => void, interval: number = 10000): () => void {
    const intervalId = setInterval(async () => {
      try {
        const data = await this.getAllRealTimeData()
        callback(data)
      } catch (error) {
        console.error('实时数据更新失败:', error)
      }
    }, interval)

    // 立即执行一次
    this.getAllRealTimeData().then(callback).catch(console.error)

    return () => clearInterval(intervalId)
  }

  /**
   * 关闭连接
   */
  async close(): Promise<void> {
    await mongoDB.disconnect()
  }
}

// 创建全局实例
export const databaseService = new DatabaseService()

export default databaseService
